#ifndef HEIGHTMAP_HPP_INCLUDED
#define HEIGHTMAP_HPP_INCLUDED

#include <GL/gl.h>

#include <vector>

namespace hex {

class heightmap
{
public:
	heightmap();
	heightmap(int width, int height);
	int width() const { return width_; }
	int height() const { return height_; }

	void set(int x, int y, GLfloat value);
	void add(int x, int y, GLfloat value);

	GLfloat val(int x, int y) const;
	void gl_normal(int x, int y) const;

	bool is_on_map(int x, int y) const { return x >= 0 && y >= 0 && x < width_ && y < height_; }

	void subdivide(GLfloat variance);
	void erode(GLfloat slope, GLfloat erosion_rate);

	//the number of times the heightmap has been divided.
	int subdivisions() const { return subdivisions_; }

	//if you had two points that were adjacent before any subdivisions, this
	//will tell you how many points there are now between them.
	int points_between() const { return points_between_; }

	const heightmap* lower_detail_version(int subdiv) const;
	void calculate_normals();

	void invert_normals();
private:
	GLfloat& mutable_val(int x, int y);
	void create_lower_detail(heightmap& m) const;
	std::vector<GLfloat> map_;

	int width_, height_;
	int subdivisions_;
	int points_between_;

	mutable std::vector<heightmap> lower_detail_;

	std::vector<std::pair<GLfloat, GLfloat> > normals_;
};

}

#endif
